Skip to content

Create Week10 Mission0, 1, 2#134

Open
hyeok02 wants to merge 1 commit intomainfrom
hyeok02/week10
Open

Create Week10 Mission0, 1, 2#134
hyeok02 wants to merge 1 commit intomainfrom
hyeok02/week10

Conversation

@hyeok02
Copy link
Contributor

@hyeok02 hyeok02 commented Dec 21, 2025

📝 미션 번호

10주차 Misson 1.2, 프랙티스 1,2

📋 구현 사항

  • 랜더링 최적화
  • vercel 배포

📎 스크린샷

2025-12-21.210629.1.mp4

✅ 체크리스트

  • Merge 하려는 브랜치가 올바르게 설정되어 있나요?
  • 로컬에서 실행했을 때 에러가 발생하지 않나요?
  • 불필요한 주석이 제거되었나요?
  • 코드 스타일이 일관적인가요?

🤔 질문 사항

@hyeok02 hyeok02 requested a review from woojo230 December 21, 2025 12:13
@hyeok02 hyeok02 self-assigned this Dec 21, 2025
@github-actions
Copy link

🤖 Gemini 코드리뷰 결과

안녕하세요. 시니어 프론트엔드 개발자로서 제공해주신 Pull Request의 모든 파트(1/7 ~ 7/7)를 면밀히 검토했습니다.

전반적으로 모던 프론트엔드 기술 스택(React Query, React Hook Form, Zod, Tailwind CSS)을 효과적으로 적용하고 계시며, useCallback, useMemo, memo와 같은 React 최적화 훅에 대한 이해와 적용 노력이 돋보입니다. 특히, 계산 비용이 큰 로직에 useMemo를 사용하거나, loading="lazy" 속성을 통해 성능을 개선하려는 시도는 매우 긍정적입니다.

아래는 모든 파트의 리뷰 내용을 통합하여 프로젝트 전반의 설정, 의존성, API 계층, 커스텀 훅, 컴포넌트, 유틸리티 파일에 걸쳐 성능, 타입 안정성, 코드 품질, 유지보수성 측면에서 개선할 수 있는 구체적인 제안들을 정리한 내용입니다.


리뷰 요약 및 핵심 권고사항

이번 PR에서 가장 중요하게 개선을 권고하는 사항들은 다음과 같습니다:

  1. React 19 및 babel-plugin-react-compiler 사용 재검토: 아직 안정화되지 않은 기술이므로 프로덕션 적용 시 신중한 접근과 충분한 테스트가 필요합니다.
  2. ESLint 타입 기반 규칙 및 Flat Config 마이그레이션: ESLint 9.x에 맞춰 Flat Config로 마이그레이션하고, @typescript-eslint/recommended-type-checked 플러그인을 활성화하여 타입스크립트 코드의 안정성을 극대화하세요.
  3. react-query@tanstack/react-query 최신 버전으로 마이그레이션: 더 이상 유지보수되지 않는 react-query v3 대신 최신 버전을 사용하여 성능, 번들 크기, 타입 지원을 개선하세요.
  4. axios.ts의 환경 변수 및 토큰 관리 개선: baseURL 및 토큰 이름을 환경 변수와 상수로 분리하고, 인증 실패 처리 로직을 중앙 집중화하여 유지보수성을 높이세요.
  5. 커스텀 훅 및 컴포넌트의 useCallbackmemo 적용 패턴 개선: CountButton, TextInput, handleIncreaseCount 등에서 useCallback의 의존성 배열 및 memo의 효과를 저해하는 인라인 함수 사용 패턴을 최적화하세요.
  6. TMDB API 요청 효율화 및 대규모 리스트 렌더링 최적화: useMovieSearch에서 include_adult 파라미터를 서버 요청에 포함하고, UseMemoPage와 같이 대규모 데이터를 렌더링할 때 가상화(Virtualization) 또는 페이지네이션을 고려하세요.

통합 코드 리뷰 상세 내용

1. 프로젝트 전반: 설정 및 의존성 관리

  • React 19 버전 채택 전략 및 babel-plugin-react-compiler 사용 재검토
    • 문제점: reactreact-dom^19.2.0 (RC 버전)으로 설정되어 있고, babel-plugin-react-compiler와 같은 실험적인 플러그인을 사용 중입니다. 안정화되지 않은 버전은 예상치 못한 버그를 초래할 수 있습니다.
    • 개선 제안: 프로덕션 환경이라면 React 18과 같은 안정적인 버전을 사용하고, React 19는 정식 릴리스 및 충분한 테스트 후에 도입하는 것을 권장합니다. 실험적인 기능 테스트 목적이라면 문서화를 명확히 하세요.
  • ESLint Flat Config 마이그레이션 및 타입 기반 규칙 강화
    • 문제점: ESLint 9.x를 사용하면서 기존 eslintrc 설정이 아닌 Flat Config(eslint.config.js)로의 마이그레이션이 필요하며, 타입스크립트의 강력한 타입 정보를 활용하는 린팅 규칙이 충분히 적용되지 않았습니다.
    • 개선 제안:
      • ESLint Flat Configuration 시스템으로 전환하고 기존 규칙들을 올바르게 마이그레이션하세요.
      • .eslintrc.cjs 또는 eslint.config.js@typescript-eslint/recommended-type-checked 또는 strict-type-checked 플러그인을 추가하여 타입 정보 기반의 엄격한 린팅을 활성화합니다.
      • eslint-plugin-react를 설치하고 plugin:react/recommended, plugin:react/jsx-runtime을 추가하여 React 컴포넌트 린팅을 강화합니다.
      • react-refresh/only-export-components 규칙의 수준을 'warn'에서 'error'로 변경하여 HMR(Hot Module Replacement) 문제를 방지합니다.
  • react-query@tanstack/react-query로 마이그레이션
    • 문제점: react-query v3는 더 이상 활발히 유지보수되지 않으며, @tanstack/react-query로 이름이 변경되었습니다.
    • 개선 제안: react-query v3 의존성을 제거하고 @tanstack/react-query v4 또는 v5를 설치하여 성능 최적화, 번들 크기 개선, 새로운 기능 및 더 나은 타입 지원을 활용하세요. 관련 src 코드의 로직도 새로운 API에 맞게 업데이트해야 합니다.
  • TypeScript 최신 버전 활용 및 엄격 모드 활성화
    • 문제점: typescript: "^5.2.2"를 사용 중이며, 엄격한 타입 검사 옵션 설정 여부를 알 수 없습니다.
    • 개선 제안: TypeScript를 최신 안정 버전(예: ^5.4.x 또는 ^5.5.x)으로 업데이트하고, tsconfig.json에서 strict: true, noImplicitAny: true, strictNullChecks: true 등 엄격한 타입 검사 옵션을 활성화하여 타입 안전성을 극대화하세요.
  • @hookform/resolvers 버전 동기화
    • 문제점: react-hook-form v7.55.0과 @hookform/resolvers v5.0.1이 명시되어 있어 타입 호환성 문제가 발생할 수 있습니다.
    • 개선 제안: react-hook-form v7에 맞춰 @hookform/resolvers도 최신 v7 호환 버전으로 업데이트하여 타입 불일치로 인한 잠재적인 문제를 해결합니다.
  • use-fetch 라이브러리 검토
    • 문제점: use-fetch와 같은 작은 유틸리티 라이브러리 의존성은 유지보수 위험이 될 수 있으며, @tanstack/react-query와 기능이 중복될 수 있습니다.
    • 개선 제안: use-fetch의 필요성을 평가하고 @tanstack/react-query 또는 axios를 래핑하는 방식으로 대체하여 종속성을 줄이고 코드의 일관성을 높이는 것을 고려합니다.
  • 핵심 dependencies의 버전 고정 및 engines 필드 명시
    • 문제점: react, tailwindcss 등 핵심 dependencies에 캐럿(^) 연산자가 사용되어 빌드 일관성을 저해할 수 있으며, Node.js 버전이 명시되어 있지 않아 개발 환경 간 불일치를 초래할 수 있습니다.
    • 개선 제안: package.json의 핵심 dependencies는 정확한 버전(예: 19.2.3)을 명시하여 모든 환경에서 동일한 패키지 버전을 사용하도록 강제합니다. 또한, engines.node 필드를 추가하여 프로젝트가 지원하는 최소 Node.js 버전을 명시하세요.
  • 정기적인 종속성 보안 감사 및 번들 사이즈 모니터링
    • 개선 제안: Dependabot 또는 Renovate Bot을 사용하여 종속성 업데이트를 자동화하고, pnpm audit (또는 npm audit)를 CI/CD 파이프라인에 통합하여 보안 취약점을 감지하세요. rollup-plugin-visualizer와 같은 번들 사이즈 분석 도구를 통합하여 성능 저하를 미리 식별합니다.

2. API 계층 (src/apis)

  • src/apis/axios.ts
    • 타입 안전성 강화:
      • error.config_retry 속성을 추가하는 부분에 대한 명시적인 타입 확장(CustomAxiosRequestConfig 인터페이스 정의)이 필요합니다.
      • 토큰 갱신 API 응답(response.data.accessToken)과 catch 블록의 refreshError에 대한 타입을 명확히 정의합니다 (예: RefreshTokenResponse 인터페이스, AxiosError 타입 가드 활용).
    • 리팩토링 및 유지보수성 향상:
      • baseURL과 토큰 갱신 API URL을 하드코딩하는 대신 .env 파일에 VITE_API_BASE_URL과 같은 환경 변수로 관리하여 유연성을 확보합니다.
      • accessToken, refreshToken 문자열을 상수로 분리하여 오타를 방지하고 유지보수성을 높입니다.
      • 토큰 삭제 및 로그인 페이지 리다이렉션 로직을 handleAuthError와 같은 별도 유틸리티 함수로 분리하여 코드의 가독성 및 응집도를 높입니다.
  • src/apis/signup.ts
    • 타입 안전성 강화: signUpUser 함수가 반환하는 response.data의 타입을 명시적으로 지정하는 인터페이스(예: SignUpResponse)를 정의합니다.
    • 데이터 처리 및 에러 핸들링 개선:
      • bio: "안녕하세요. 저는 매튜입니다."와 같이 하드코딩된 bio 필드의 의도를 명확히 하고, 필요에 따라 SignUpPayload에 포함하거나 상수로 추출합니다.
      • API 호출 실패 시 axios.isAxiosError를 사용하여 구체적인 에러(예: 409 Conflict, 400 Bad Request)를 처리하는 로직을 추가하여 사용자에게 상세한 피드백을 제공합니다.

3. 커스텀 훅 계층 (src/hooks)

  • src/hooks/usemoviesearch.ts - 클라이언트 측 성인 콘텐츠 필터링 비효율
    • 문제점: includeAdult 옵션에 따라 API 응답을 클라이언트 측에서 필터링하고 있어 비효율적입니다.
    • 개선 제안: TMDB API는 include_adult 파라미터를 지원하므로, 이 필터링을 서버 측에서 수행하도록 API 요청(axios.getparams)에 포함하여 네트워크 트래픽 및 클라이언트 처리량을 절감합니다.
  • src/hooks/usemoviedetail.ts - movieId 타입 안전성 강화
    • 문제점: useParams<{ movieId: string }>() 이후 movieId as string으로 타입 단언을 사용하고 있습니다.
    • 개선 제안: movieIdstring | undefined로 명확하게 타입을 지정하고, useQueryenabled: !!movieId 조건을 활용하며, fetchMovieDetails 함수에서도 이를 인지하도록 하여 타입 단언을 줄입니다.
  • src/hooks/useloginform.ts, src/hooks/usesignupform.ts - 인증 토큰 관리 로직 중복 및 에러 핸들링
    • 문제점: localStorage.setItem("accessToken", ...) 등 인증 토큰 저장 로직이 여러 곳에서 반복됩니다.
    • 개선 제안: 이를 별도의 유틸리티 함수나 AuthContext, 또는 AuthService 모듈로 추출하여 중앙 집중식으로 관리하고, axios.isAxiosError를 활용한 에러 핸들링과 함께 사용자에게 토스트 알림 등의 형태로 에러 메시지를 제공합니다.
  • src/hooks/usecallbackpage.ts (handleIncreaseCount) - useCallback 의존성 배열 최적화
    • 문제점: handleIncreaseCount의 의존성 배열에 [count]가 포함되어 있어 count 변경 시 함수가 재생성되며, CountButtonmemo 효과를 상쇄합니다.
    • 개선 제안: setCount에 함수형 업데이트(prevCount => prevCount + number)를 사용하여 count를 의존성 배열에서 제거함으로써 handleIncreaseCount의 참조 안정성을 확보합니다.
  • src/hooks/usememopage.ts (handleChangeText) - useCallback 적용 고려
    • 개선 제안: handleChangeText 함수도 useCallback으로 감싸 참조 안정성을 확보하면, TextInputReact.memo로 래핑될 경우 불필요한 리렌더링을 방지할 수 있습니다.
  • 전반적인 커스텀 훅 주석 품질 향상
    • 개선 제안: useLocalStorage, useMovieDetail, useMovieSearch 등 복잡하거나 중요한 로직을 담고 있는 커스텀 훅에 JSDoc 스타일의 주석을 추가하여 훅의 목적, 인자, 반환 값 등을 명확히 설명합니다.

4. 컴포넌트 및 페이지 계층 (src/components, src/pages)

  • src/App.tsx, src/main.tsx: 표준적인 React 애플리케이션 구성이며, StrictMode 사용은 좋은 개발 습관입니다.
  • src/components/movie-detail/detailcontent.tsx
    • 성능: 영화 상세 페이지 배경 이미지(movie?.poster_path)의 크기가 w500으로 고정되어 있습니다. 다양한 화면 크기에 맞춰 srcset 또는 <picture> 태그, 미디어 쿼리 등을 활용하여 반응형 이미지 기법을 적용해 적절한 해상도의 이미지를 로드하도록 고려합니다.
    • 타입스크립트: Movie 인터페이스의 필수/선택 필드를 API 스펙에 맞춰 명확히 선언하여 (id, title, poster_path 등은 필수) 타입 안정성을 높이고 불필요한 널 체크를 줄입니다.
  • src/components/movie/movie-item.tsx
    • 코드 품질: Item이라는 컴포넌트 이름은 불명확합니다. MovieList 내에서 사용되므로 MovieItem으로 변경하여 의도를 명확히 합니다.
  • src/components/CountButton.tsx & src/components/TextInput.tsx
    • 성능: memo로 래핑되어 있지만, <button>onClick<input>onChange 핸들러가 인라인 함수로 정의되어 매 렌더링마다 새로운 함수가 생성됩니다. 이는 memo의 효과를 상쇄할 수 있습니다.
    • 개선 제안: 내부 이벤트 핸들러를 useCallback으로 래핑하여 참조 안정성을 확보합니다.
    • 코드 품질: 디버깅을 위한 console.log는 프로덕션 코드에서 제거하거나 조건부로 활성화되도록 변경합니다.
    • 타입스크립트: 인라인 화살표 함수의 반환 타입으로 : void를 명시하는 것은 대부분의 경우 불필요하므로 제거하여 가독성을 높입니다.
  • 반복되는 영화 카테고리 페이지 (now-playing.tsx, popular.tsx, top-rated.tsx, upcoming.tsx)
    • 중복 코드: 이 파일들은 usePaginatedMovies 훅을 사용하여 다른 type 값만 전달할 뿐 동일한 구조를 가집니다.
    • 개선 제안: 단일의 재사용 가능한 컴포넌트(예: MovieCategoryPage.tsx)로 통합하고, type 값을 useParamsuseLocation을 통해 동적으로 받아오도록 리팩토링합니다. src/routes/routes.tsx에서도 이 단일 컴포넌트를 사용하도록 간소화합니다.
  • JSX/CSS에 직접적인 '매직 넘버' 사용 지양
    • 문제점: src/pages/login.tsx, src/pages/signup.tsx 등 여러 컴포넌트에서 h-[360px], pt-[150px]와 같은 구체적인 픽셀 값을 Tailwind CSS 클래스에 직접 사용하고 있습니다.
    • 개선 제안: Tailwind의 기본 간격 스케일을 사용하거나, 필요한 경우 Tailwind 구성 파일에 사용자 정의 값을 추가하여 디자인 시스템의 일관성과 유지보수성을 확보합니다.
  • src/pages/UseCallbackPage.tsx - HTML 시맨틱 구조 개선
    • 개선 제안: 관련 있는 콘텐츠를 section과 같은 HTML5 시맨틱 요소로 묶어 구조를 명확히 하고, 필요한 경우 aria-labelledby와 같은 접근성 속성을 추가하여 스크린 리더 사용자에게 더 나은 경험을 제공합니다.
  • src/pages/UseMemoPage.tsx
    • 성능 및 사용자 경험: limit 값이 커져 수천, 수만 개의 소수가 primes 배열에 포함될 경우, 모든 소수를 DOM에 직접 렌더링하는 것은 브라우저 성능 저하를 야기할 수 있습니다.
    • 개선 제안: react-virtualizedreact-window와 같은 가상화 라이브러리를 사용하여 화면에 보이는 부분만 렌더링하거나, 페이지네이션 기능을 도입하여 사용자 경험을 향상시키고 렌더링 부하를 줄이는 것을 고려해볼 수 있습니다.
    • 타입 안정성: setLimit(Number(e.target.value)) 코드에서 Number(e.target.value)NaN을 반환할 수 있으므로, parseInt를 사용하고 결과값이 NaN이거나 유효하지 않은 범위(예: 음수)인 경우를 처리하는 로직을 추가하여 안정성을 높입니다.

5. 유틸리티 계층 (src/utils)

  • src/utils/math.ts - isPrime 함수 루프 조건 및 증감문 최적화
    • 문제점: 현재 isPrime 함수는 소수 판별 시 i + i <= num 조건을 사용하고 짝수 검사를 반복하여 불필요하게 많은 반복을 수행합니다.
    • 개선 제안: 루프 조건을 i * i <= num (즉, i <= Math.sqrt(num))으로 변경하고, i += 2를 사용하여 홀수만 검사하도록 최적화하여 성능을 향상시킵니다.
  • src/utils/math.ts - findPrimeNumbers 함수 결과 반환 방식 개선
    • 문제점: sieve.map(...).filter(...)는 중간 배열을 생성하므로 max 값이 매우 클 경우 추가적인 메모리 소비가 발생할 수 있습니다.
    • 개선 제안: mapfilter 대신 for 루프를 사용하여 primes 배열을 직접 구성하는 것이 메모리 사용량 측면에서 미세하게 더 효율적일 수 있습니다. (현재 코드가 가독성이 좋으므로 필수적인 개선은 아니며, 극단적인 성능/메모리 요구사항이 있을 때 고려할 수 있습니다.)

결론

이 PR은 전반적으로 React, TypeScript 및 모던 프론트엔드 도구들을 잘 활용하고 있다는 인상을 주었습니다. 위에서 제시된 제안들은 주로 설정의 견고함, 타입 안전성 극대화, 렌더링 및 계산 성능 최적화, 그리고 코드의 유지보수성 및 확장성 향상에 중점을 둔 것입니다.

이러한 개선 사항들을 반영한다면 프로젝트의 품질과 개발 경험을 더욱 높일 수 있을 것이라고 생각합니다. 궁금한 점이 있다면 언제든지 질문해주세요.

Copy link
Collaborator

@woojo230 woojo230 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10주차도 고생하셨습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants